<template>
  <div ref="canvas"></div>
</template>

<script lang="ts" setup>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { ref, onMounted } from "vue";

// 画布
const canvas = ref<any>('');
// 场景
const scene = new THREE.Scene();
// 几何体
const geometry = new THREE.BufferGeometry();
// 圆弧半径
const r = 100;
// 分段数量
const n = 50;
// 两个相邻点间隔弧度
// 完整圆形
const sp = 2 * Math.PI / n;
// 半圆
// const sp = Math.PI / n;
// 批量生成圆弧上的顶点数据
const arr = [];
for (let i = 0; i < n; i++) {
  // 当前点弧度
  const angle = sp * i;
  // 以原点为中心，在XOY平面上生成圆弧上的顶点数据
  const x = r * Math.cos(angle);
  const y = r * Math.sin(angle);
  arr.push(x, y, 0);
}
// 顶点数组
const vertices = new Float32Array(arr);
// 3个一组表示一个顶点的坐标
const positionAttr = new THREE.BufferAttribute(vertices, 3);
// 设置位置属性
geometry.attributes.position = positionAttr;
// 材质
const material = new THREE.LineBasicMaterial({
  color: 0xff0000,
  side: THREE.DoubleSide,
});
// 网格模型 Line
const line = new THREE.LineLoop(geometry, material);
scene.add(line);
// 环境光
const ambient = new THREE.AmbientLight(0xffffff, 0.8);
scene.add(ambient);
// 相机
const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 2000);
camera.position.set(200, 200, 200);
camera.lookAt(line.position);
// 渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true,
});
renderer.setClearColor(0xffffff);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// 渲染函数
const render = () => {
  renderer.render(scene, camera);
  requestAnimationFrame(render);
};
// 相机控件
const orbitControl = new OrbitControls(camera, renderer.domElement);
orbitControl.update();

onMounted(() => {
  canvas.value.appendChild(renderer.domElement);
  render();
});

</script>
